package com.tqjc.execute.step;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tqjc.area.entity.Roller;
import com.tqjc.area.entity.SteelPlate;
import com.tqjc.area.service.RollerService;
import com.tqjc.area.service.SteelPlateService;
import com.tqjc.execute.cache.TaskStatus;
import com.tqjc.execute.cache.entity.WorkStatus;
import com.tqjc.execute.consts.WorkConst;
import com.tqjc.execute.exception.TaskRunningException;
import com.tqjc.execute.exception.UpstreamSteelInfoException;
import com.tqjc.execute.task.entity.Task;
import com.tqjc.execute.task.entity.TaskApart;
import com.tqjc.execute.task.service.impl.TaskApartServiceImpl;
import com.tqjc.execute.task.service.impl.TaskServiceImpl;
import com.tqjc.execute.thread.aysn.AysnEleTaskLogThread;
import com.tqjc.execute.utils.DateUtils;
import com.tqjc.execute.utils.HttpPLCUtils;
import com.tqjc.execute.utils.PlcOperator;
import com.tqjc.execute.work.CraneWorkFactory;
import com.tqjc.execute.work.callback.TaskCallback;
import com.tqjc.system.core.threadpool.ThreadPoolManager;
import com.tqjc.system.core.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Date;

@Slf4j
@Component
@Scope("prototype")
public class PlaceSteelPlateRollerStep extends TaskApart implements TaskCallback {  //放置钢板到辊道上步骤

    @Resource
    PlcOperator plcOperator;


    @Resource
    SteelPlateService steelPlateService;

    @Resource
    RollerService rollerService;

    @Resource
    CraneWorkFactory craneWorkFactory;

    @Resource
    TaskStatus taskStatus;

    @Value("${server_host}")
    private String serverHost;

    @Autowired
    private RestTemplate restTemplate;

    public PlaceSteelPlateRollerStep() {
        this.setType("place-roller");
    }

    @Override
    public void onPreExecute() {
        try {
            setBeginTime(new Date());

            //设置工作状态
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setNowStep(getType());
            status.setNowSteelNum(getTask().getSteelNo());
            status.setUnnormalStatus("");
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(getCraneType()+getType()+"前置出现异常", e);
        }

    }

    @Override
    public void onPostExecute() {
        try {
            setEndTime(new Date());

            WorkConst.cacheTaskMap.remove(getCraneType()+"_task");  //放板成功了，缓存中的task没用了，释放

            //保存钢板信息
            Task task = this.getTask();
            SteelPlate steel4Online = task.getSteel4Online();
            //所属层数
            steel4Online.setArea("stock_2");
            steel4Online.setTier(0);
            steel4Online.setInStock(0);
            steelPlateService.insert(steel4Online);

            getTask().setTaskStatus(2);
            SpringUtils.getBean(TaskServiceImpl.class).saveOrUpdate(getTask());
            SpringUtils.getBean(TaskApartServiceImpl.class).insert(this);

            //TODO 传送钢板编号至下级抛丸机PLC

            //修改步骤状态
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setNowStep("");
            status.setNowSteelNum("");
            status.setUnnormalStatus("");
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
            //清除bean
            destroy();
        } catch (Exception e) {
            log.error(getCraneType()+getType()+"后置出现异常", e);
            e.printStackTrace();
        }
    }



    @Override
    public void setTaskApartByTask(Task task) {
        this.setCallback(this);
        super.setTaskApartByTask(task);

    }

    @Override
    public void customAction() throws TaskRunningException, UpstreamSteelInfoException {
        try {
            String craneType = this.getTask().getCraneType();
            Roller roller=rollerService.queryById(this.getTask().getRollerId());
            String[] lockArr= roller.getLockSignal().split("-");
            //写一级辊道锁定信号
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,lockArr[1],HttpPLCUtils.dataTypeList.get("bool"),"TRUE",lockArr[0],true);
            //向天车写辊道锁定信息信号
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.10",HttpPLCUtils.dataTypeList.get("bool"),"TRUE","辊道锁定",false);

            //异步启动自动任务监控线程
            AysnEleTaskLogThread aysnEleTaskLogThread = AysnEleTaskLogThread.builder().flag(true).craneName(craneType).host(serverHost).restTemplate(restTemplate).build();
            ThreadPoolManager.getInstance().execute(aysnEleTaskLogThread);


            //this.setSteelId(getTask().getSteelNum());
            //清半自动标志
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.1",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","半自动标志",false);

            //清任务id
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.2",HttpPLCUtils.dataTypeList.get("int16"),"0","任务ID",false);
            //清任务启动信号
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.8.2",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","任务启动",false);
            //清任务完成信号
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.120.5",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","放板任务完成",false);

            //写入任务ID
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.2",HttpPLCUtils.dataTypeList.get("int16"),"2","任务ID",false);
            //写入任务启动
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.8.2",HttpPLCUtils.dataTypeList.get("bool"),"TRUE","任务启动",false);
            log.info("{}天车自动放板步骤任务启动",getTask().getCraneType());
            boolean isFinished = false;
            String isFinishStr="";
            Date startDate=new Date();
            while (!isFinished) {
                boolean overTime= DateUtils.isOverTimeByNow(startDate,180000);//超过100秒未完成，退出等待。
                if(overTime){
                    //log.info("等待{}天车自动放板步骤任务完成超时",getTask().getCraneType());
                    WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
                    status.setUnnormalStatus("等待放板任务完成超时");
                    taskStatus.setWorkStatusByCraneType(getCraneType(), status);
                    boolean isStartLogo= craneWorkFactory.getCraneWorkImpl(getCraneType()).getData().getStartLogo();
                    if(!isStartLogo){
                        break;
                    }
                    //return;
                }
                isFinishStr= HttpPLCUtils.plcReadbc(restTemplate,serverHost,craneType,"放板任务完成",false);
                if ("true".equalsIgnoreCase(isFinishStr)) {
                    log.info("PLC反馈{}天车自动放板步骤任务完成",getTask().getCraneType());
                    //清一级辊道锁定信号
                    HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,lockArr[1],HttpPLCUtils.dataTypeList.get("bool"),"FALSE",lockArr[0],true);
                    //清天车辊道锁定信息信号
                    HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.10",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","辊道锁定",false);

                    //清任务id
                    HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.2",HttpPLCUtils.dataTypeList.get("int16"),"0","任务ID",false);
                    //清任务启动信号
                    HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.8.2",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","任务启动",false);
                    //清任务完成信号
                    HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.120.5",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","放板任务完成",false);
                    isFinished = true;

                }
                String taskFlag = HttpPLCUtils.plcReadbc(restTemplate, serverHost, craneType, "任务中止", false);
                if("true".equalsIgnoreCase(taskFlag)){
                    log.info("天车执行自动放板步骤时，监听到任务中止信号");
                    aysnEleTaskLogThread.setFlag(false);
                    throw new TaskRunningException("任务人工停止",craneType);
                }
            }
            //动作结束，关闭打印线程日志
            aysnEleTaskLogThread.setFlag(false);
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setUnnormalStatus("");
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
        } catch (UpstreamSteelInfoException ee){
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setUnnormalStatus(ee.getMessage());
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
            throw ee;
        }catch (Exception e) {
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setUnnormalStatus(e.getMessage());
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
            e.printStackTrace();
            throw new TaskRunningException(e.getMessage(), getTask().getCraneType());
        }
    }


    @Override
    public void destroy() throws Exception {

    }


    @Override
    public void afterPropertiesSet() throws Exception {

    }
}
